Build a Completion UI App
A completion frontend app may operate on one well or on several wells associated with a frac fleet and pad. The app must handle both shapes because Corva dashboards can provide a single selected well or a wells collection.
What Corva supplies
For the completion segment, Corva UI maps the operational context as follows:
| Context value | Meaning | Common use |
|---|---|---|
fracFleet | Selected frac fleet and its pad relationships | Fleet context, current pad, SimulFrac lines |
well | Selected well on an asset-scoped dashboard | Single-well completion views |
wells | Wells available on a general or multi-well dashboard | Pad and multi-well views |
appSettings | Saved settings, including pad-mode selections | Customer-selected completion mode and filters |
Access these values with useAppCommons from @corva/ui/effects.
1. Confirm the manifest segment
Your generated manifest.json should contain:
{
"application": {
"type": "ui",
"segments": ["completion"],
"ui": {
"use_app_header_v3": true
}
}
}
The default completion behavior is a Frac Multi-Well App. Add a different completionAppType only when the app is specifically a pad, wireline, pumpdown, or single-well workflow.
2. Normalize one well and many wells
Keep the standard app shell, then normalize the context before rendering or querying data:
import { AppContainer, AppHeader, EmptyState } from '@corva/ui/componentsV2';
import { useAppCommons } from '@corva/ui/effects';
export default function App() {
const { appKey, fracFleet, well, wells = [] } = useAppCommons();
const visibleWells = wells.length ? wells : well ? [well] : [];
if (!visibleWells.length) {
return (
<AppContainer header={<AppHeader />} testId={appKey}>
<EmptyState title="Select a completion well or pad" />
</AppContainer>
);
}
return (
<AppContainer header={<AppHeader />} testId={appKey}>
<main>
<h2>{fracFleet?.name ?? 'Completion wells'}</h2>
<ul>
{visibleWells.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</main>
</AppContainer>
);
}
Do not assume wells always exists, and do not create [well] without checking that well is defined.
3. Understand pad mode
For a multi-well completion app, AppHeader can show the pad-mode selector automatically when:
- The app segment is
completion. - A
fracFleetand a non-emptywellscollection are available. - The dashboard is not already scoped to a single
well. padModeDisabledis not set onAppHeader.
The selector stores its current choice in appSettings.settingsByAsset. If the body of your app must use the same selected wells, use usePadSelectorSelectedWells from @corva/ui/effects rather than implementing a second selection model.
See Completion Pad Mode for the supported modes and a complete example.
4. Choose the completion app type
corva-ui supports these values:
completionAppType | Intended workflow |
|---|---|
Pad Apps | Pad-wide data and customer-selected wells |
Frac & Wireline Multi-Well Apps | Combined frac and wireline views |
Frac Multi-Well Apps | Frac views across the pad; default |
Wireline Multi-Well Apps | Wireline views across multiple wells |
Pumpdown Multi-Well Apps | Pumpdown views across multiple wells |
Frac Single Well Apps | Active frac well plus custom well selection |
Wireline Single Well Apps | Active wireline well plus custom selection |
Pumpdown Single Well Apps | Active pumpdown well plus custom selection |
For example:
{
"application": {
"ui": {
"completionAppType": "Frac & Wireline Multi-Well Apps",
"enableSimulFracInPadSelect": true,
"disableActiveWellsInPadSelect": false
}
}
}
Use enableSimulFracInPadSelect only when the app should expose frac-fleet line selection. The line and well relationships come from fracFleet.pad_frac_fleets.
5. Load data for every selected well
Completion dataset requests still use each well's asset_id. Derive the selected list first, then request or subscribe only to those asset IDs. Update the requests when pad mode changes.
Use the Data API reference for dataset parameters. Dev Center frontend apps should call the authenticated corvaDataAPI and socketClient exports from @corva/ui/clients; never place customer credentials in browser code.
Continue with: